import { HttpException, HttpStatus } from '@nestjs/common';

/**
 * 零隐患MFIS规范 - Scoring模块异常定义
 * 所有异常都有明确的错误代码和脱敏的错误消息
 */

// 基础评分异常
export class ScoringException extends HttpException {
  constructor(message: string, errorCode: string, statusCode: HttpStatus = HttpStatus.INTERNAL_SERVER_ERROR) {
    super(
      {
        success: false,
        error_code: errorCode,
        message: sanitizeErrorMessage(message),
        timestamp: new Date().toISOString(),
      },
      statusCode
    );
  }
}

// 文件验证异常
export class FileValidationException extends ScoringException {
  constructor(message: string) {
    super(message, 'FILE_VALIDATION_FAILED', HttpStatus.BAD_REQUEST);
  }
}

// AI推理异常
export class AiInferenceException extends ScoringException {
  constructor(message: string, originalError?: Error) {
    const sanitizedMessage = originalError
      ? 'AI推理服务暂时不可用，请稍后重试'
      : message;

    super(sanitizedMessage, 'AI_INFERENCE_FAILED', HttpStatus.SERVICE_UNAVAILABLE);
  }
}

// 任务未找到异常
export class TaskNotFoundException extends ScoringException {
  constructor(taskId: number) {
    super(`任务 ${taskId} 不存在`, 'TASK_NOT_FOUND', HttpStatus.NOT_FOUND);
  }
}

// 未授权访问异常
export class UnauthorizedAccessException extends ScoringException {
  constructor(resource: string) {
    super(`无权访问${resource}`, 'UNAUTHORIZED_ACCESS', HttpStatus.FORBIDDEN);
  }
}

// 任务状态异常
export class TaskStateException extends ScoringException {
  constructor(currentStatus: string, action: string) {
    super(
      `任务状态 ${currentStatus} 不允许执行 ${action} 操作`,
      'INVALID_TASK_STATE',
      HttpStatus.CONFLICT
    );
  }
}

// 队列异常
export class QueueException extends ScoringException {
  constructor(message: string) {
    super(message, 'QUEUE_ERROR', HttpStatus.SERVICE_UNAVAILABLE);
  }
}

// 缓存异常
export class CacheException extends ScoringException {
  constructor(message: string) {
    super(sanitizeErrorMessage(message), 'CACHE_ERROR', HttpStatus.INTERNAL_SERVER_ERROR);
  }
}

// 数据库异常
export class DatabaseException extends ScoringException {
  constructor(message: string, originalError?: Error) {
    const sanitizedMessage = originalError
      ? '数据库操作失败，请稍后重试'
      : sanitizeErrorMessage(message);

    super(sanitizedMessage, 'DATABASE_ERROR', HttpStatus.INTERNAL_SERVER_ERROR);
  }
}

/**
 * 错误消息脱敏函数
 * 解决隐患 #14 日志信息泄露
 */
function sanitizeErrorMessage(message: string): string {
  if (!message) return '未知错误';

  return message
    // 移除文件路径
    .replace(/[A-Za-z]:\\[^\\s]*/g, '[文件路径]')
    .replace(/\/[^\\s]*\/[^\\s]*/g, '[文件路径]')

    // 移除敏感信息
    .replace(/password[=:]\s*\S+/gi, 'password=***')
    .replace(/token[=:]\s*\S+/gi, 'token=***')
    .replace(/key[=:]\s*\S+/gi, 'key=***')
    .replace(/secret[=:]\s*\S+/gi, 'secret=***')
    .replace(/auth[=:]\s*\S+/gi, 'auth=***')

    // 移除可能的数据库连接信息
    .replace(/mysql:\/\/[^@]+@[^\/]+/g, 'mysql://***@***/')
    .replace(/redis:\/\/[^@]+@[^\/]+/g, 'redis://***@***/')

    // 移除IP地址（可选，根据需要）
    .replace(/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b/g, '[IP地址]')

    // 限制长度
    .substring(0, 200)
    .trim() || '错误信息已被过滤';
}

/**
 * 异常代码枚举
 */
export enum ErrorCode {
  // 通用错误
  UNKNOWN_ERROR = 'UNKNOWN_ERROR',
  VALIDATION_FAILED = 'VALIDATION_FAILED',

  // 文件相关
  FILE_VALIDATION_FAILED = 'FILE_VALIDATION_FAILED',
  FILE_TOO_LARGE = 'FILE_TOO_LARGE',
  UNSUPPORTED_FILE_TYPE = 'UNSUPPORTED_FILE_TYPE',
  FILE_CORRUPTED = 'FILE_CORRUPTED',

  // AI服务相关
  AI_INFERENCE_FAILED = 'AI_INFERENCE_FAILED',
  AI_SERVICE_UNAVAILABLE = 'AI_SERVICE_UNAVAILABLE',
  AI_TIMEOUT = 'AI_TIMEOUT',
  AI_CIRCUIT_BREAKER_OPEN = 'AI_CIRCUIT_BREAKER_OPEN',

  // 任务相关
  TASK_NOT_FOUND = 'TASK_NOT_FOUND',
  TASK_CREATION_FAILED = 'TASK_CREATION_FAILED',
  TASK_PROCESSING_FAILED = 'TASK_PROCESSING_FAILED',
  INVALID_TASK_STATE = 'INVALID_TASK_STATE',

  // 权限相关
  UNAUTHORIZED_ACCESS = 'UNAUTHORIZED_ACCESS',
  FORBIDDEN_OPERATION = 'FORBIDDEN_OPERATION',

  // 系统相关
  QUEUE_ERROR = 'QUEUE_ERROR',
  CACHE_ERROR = 'CACHE_ERROR',
  DATABASE_ERROR = 'DATABASE_ERROR',
  CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',

  // 网络相关
  NETWORK_ERROR = 'NETWORK_ERROR',
  TIMEOUT_ERROR = 'TIMEOUT_ERROR',
}

/**
 * 异常处理工具类
 */
export class ExceptionUtils {
  /**
   * 创建用户友好的错误响应
   */
  static createUserFriendlyResponse(exception: any): any {
    const timestamp = new Date().toISOString();

    if (exception instanceof ScoringException) {
      return exception.getResponse();
    }

    // 处理其他类型的异常
    const statusCode = exception.status || exception.statusCode || HttpStatus.INTERNAL_SERVER_ERROR;
    const message = sanitizeErrorMessage(exception.message || '未知错误');

    return {
      success: false,
      error_code: ErrorCode.UNKNOWN_ERROR,
      message,
      timestamp,
      path: exception.path || '',
    };
  }

  /**
   * 记录异常日志（脱敏后）
   */
  static logException(logger: any, exception: any, context?: string): void {
    const sanitizedError = {
      message: sanitizeErrorMessage(exception.message),
      name: exception.constructor.name,
      stack: process.env.NODE_ENV === 'development' ? exception.stack : undefined,
      context,
      timestamp: new Date().toISOString(),
    };

    logger.error('Scoring模块异常', sanitizedError);
  }

  /**
   * 判断是否为可重试的异常
   */
  static isRetryableError(exception: any): boolean {
    if (exception instanceof AiInferenceException) {
      return true;
    }

    if (exception instanceof QueueException) {
      return true;
    }

    if (exception instanceof CacheException) {
      return true;
    }

    // 网络相关异常通常可重试
    const networkErrorPatterns = [
      /timeout/i,
      /network/i,
      /connection/i,
      /ECONNRESET/i,
      /ETIMEDOUT/i,
    ];

    return networkErrorPatterns.some(pattern =>
      pattern.test(exception.message || '')
    );
  }
}